#include "util.h"
#include <glad/glad.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stbImage/stb_image.h>
#include <iostream>

using namespace std;

uint32_t util::TextureFromFile(const string& path)
{
    int width, height, channel;

    auto data = stbi_load(path.c_str(), &width, &height, &channel, 0);

    if (!data)
    {
        cerr << "Texture failed to load at path: " << path << endl;
        stbi_image_free(data);
        return 0;
    }

    GLint dataFormat = 0;
    GLenum format = 0;
    switch (channel)
    {
        case 1:
            dataFormat = GL_RED;
            format = GL_RED; break;
        case 3:
            dataFormat = GL_RGB;
            format = GL_RGB; break;
        case 4:
            dataFormat = GL_RGBA;
            format = GL_RGBA; break;
        default:
            break;
    }

    if (format == 0)
    {
        cerr << "Texture failed to load at path: " << path << endl;
        stbi_image_free(data);
        return 0;
    }

    uint32_t texId;
    glGenTextures(1, &texId);

    glBindTexture(GL_TEXTURE_2D, texId);
    glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, width, height, 0, format, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    stbi_image_free(data);
    return texId;
}

uint32_t util::TextureFromMemory(int width, int height, int channel, uint8_t* data)
{
    GLint dataFormat = 0;
    GLenum format = 0;
    switch (channel)
    {
        case 1:
            dataFormat = GL_RED;
            format = GL_RED; break;
        case 3:
            dataFormat = GL_RGB;
            format = GL_RGB; break;
        case 4:
            dataFormat = GL_RGBA;
            format = GL_RGBA; break;
        default:
            break;
    }

    if (format == 0)
    {
        cerr << "Error: channels should be 1, 3 or 4 (TextureFromMemory<uint8_t>)" << endl;
        return 0;
    }

    uint32_t texId;
    glGenTextures(1, &texId);

    glBindTexture(GL_TEXTURE_2D, texId);
    glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, width, height, 0, format, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return texId;
}
